package pl.edu.mimuw.mas.agent.behaviour;

import java.util.Iterator;

import jade.core.Agent;
import jade.core.behaviours.OneShotBehaviour;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Zachowanie agenta pozwalajace rejestrować się w dzienniku usług (DF).
 */
public class DFRegisterBehaviour extends OneShotBehaviour {
	private static final long serialVersionUID = -7639799975292459672L;

	private final Logger log = LoggerFactory.getLogger(getClass());

	private final String serviceType;
	private final String serviceOntology;

	public DFRegisterBehaviour(Agent agent, String serviceType,	String serviceOntology) {
		super(agent);
		this.serviceType = serviceType;
		this.serviceOntology = serviceOntology;
	}

	public DFRegisterBehaviour(Agent agent, String serviceType) {
		super(agent);
		this.serviceType = serviceType;
		this.serviceOntology = null;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public void action() {
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.setName(myAgent.getAID());
		
		boolean modify = false;
		String services = "";
		try {
			DFAgentDescription[] result;
			result = DFService.search(myAgent, dfd);
			if (result.length > 0) {
				// ten agent mial juz wczesniej jakies uslugi
				dfd = result[0];
				// sprawdzam czy mial juz te sama usluge zarejestrowana
				Iterator<ServiceDescription> iter = dfd.getAllServices();
				ServiceDescription sd = null;
				boolean error = false;
				while (iter.hasNext()) {
					sd = iter.next();
					services = services.concat((services.length() == 0 ? "" : ", ") + sd.getName());
					if (sd.getName().equals(serviceType) && sd.getType().equals(serviceType)) {
						error = true; // usluga o tej samej nazwie juz byla zarejestrowana
					}
				}
				if (error) {
					log.warn("{} usługa {} już zarejestrowana (aktualne usługi to <" + services + ">)", 
							myAgent.getName(), serviceType);
					return;
				}
				// czyli mial juz uslugi, ale o innych nazwach; trzeba modyfikowac
				modify = true;
			}
		} catch (FIPAException e) {
			log.error("błąd jade", e);
		}

		ServiceDescription sd = new ServiceDescription();
		sd.setName(serviceType);
		sd.setType(serviceType);
		if(serviceOntology != null) {
			sd.addOntologies(serviceOntology);	
		}
		dfd.addServices(sd);
		
		try {
			if (modify) {
				DFService.modify(myAgent, dfd);
			} else {
				DFService.register(myAgent, dfd);
			}
			services = services.concat((services.length() == 0 ? "" : ", ") + serviceType);
			log.info("{} usługa {} dodana do DF (aktualne usługi to <" + services + ">)",
					myAgent.getName(), serviceType);

		} catch (FIPAException e) {
			log.error("Błąd jade", e);
			myAgent.doDelete();			
		}
	}
}
